<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
<html><head><title>Programming in Lua : 15.5</title>
<link rel="stylesheet" type="text/css" href="pil.css">
</head>
<body>
<p class="warning">
<A HREF="contents.html"><IMG TITLE="Programming in Lua (first edition)" SRC="capa.jpg" ALT="" ALIGN="left"></A>This first edition was written for Lua 5.0. While still largely relevant for later versions, there are some differences.<BR>The third edition targets Lua 5.2 and is available at <A HREF="http://www.amazon.com/exec/obidos/ASIN/859037985X/theprogrammil3-20">Amazon</A> and other bookstores.<BR>By buying the book, you also help to <A HREF="../donations.html">support the Lua project</A>.
</p>
<table width="100%" class="nav">
<tr>
<td width="10%" align="left"><a href="15.4.html"><img border="0" src="left.png" alt="Previous"></a></td>
<td width="80%" align="center"><a href="contents.html"><font face="Helvetica,Arial,sanserif">
<font color="gray">Programming in </font><font color="blue"> Lua</font>
</font></a></td>
<td width="10%" align="right"><a href="16.html"><img border="0" src="right.png" alt="Next"></a></td>
</tr>
<tr>
<td width="10%" align="left"></td>
<td width="80%" align="center"><a href="contents.html#P2">Part II. Tables and Objects</a>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<a href="contents.html#15">Chapter 15. Packages</a></td>
<td width="10%" align="right"></td></tr>
</table>
<hr/>
<p><h2>15.5 &ndash; Other Facilities</h2>

<p>As I said earlier,
the use of tables to implement packages
allows us to use the whole power of Lua to manipulate them.
There are unlimited possibilities.
Here I will give only a few suggestions.

<p>We do not need to define all public items of a package together.
For instance, we can add a new item to our <code>complex</code> package
in a separate chunk:
<pre>
    function complex.div (c1, c2)
      return complex.mul(c1, complex.inv(c2))
    end
</pre>
(But notice that the private part is restricted to one file,
which I think is a good thing.)
Conversely, we can define more than one package in the same file.
All we have to do is to enclose each one inside a <b>do</b> block,
so that its local variables are restricted to
that block.

<p>Outside the package,
if we are going to use some operations often,
we can give them local names:
<pre>
    local add, i = complex.add, complex.i
    
    c1 = add(complex.new(10, 20), i)
</pre>
Or else, if we do not want to write the package name over and over,
we can give a shorter local name to the package itself:
<pre>
    local C = complex
    c1 = C.add(C.new(10, 20), C.i)
</pre>

<p>It is easy to write a function that unpacks a package,
putting all its names into the global namespace:
<pre>
    function openpackage (ns)
      for n,v in pairs(ns) do _G[n] = v end
    end
    
    openpackage(complex)
    c1 = mul(new(10, 20), i)
</pre>
If you are afraid of name clashes when opening a package,
you can check the name before the assignment:
<pre>
    function openpackage (ns)
      for n,v in pairs(ns) do
        if _G[n] ~= nil then
          error("name clash: " .. n .. " is already defined")
        end
        _G[n] = v
      end
    end
</pre>

<p>Because packages themselves are tables,
we can even nest packages;
that is, we can create a package inside another one.
However, this facility is seldom necessary.

<p>Another interesting facility is <em>autoload</em>,
which only loads a function if the function is actually used by the program.
When we load an autoload package,
it creates an empty table to represent the package and
sets the <code>__index</code> metamethod of the table to do the autoload.
Then, when we call any function that is not yet loaded,
the <code>__index</code> metamethod is invoked to load it.
Subsequent calls find the function already loaded;
therefore, they do not activate the metamethod.

<p>A simple way to implement autoload can be as follows.
Each function is defined in an auxiliary file.
(There can be more than one function in each file.)
Each of these files defines its functions in a standard way,
for instance like here:
<pre>
    function pack1.foo ()
      ...
    end
    
    function pack1.goo ()
      ...
    end
</pre>
However, the file does not create the package,
because the package already exists when the function is loaded.

<p>In the main package we define an auxiliary table that describes
where we can find each function:

<pre>
    local location = {
      foo = "/usr/local/lua/lib/pack1_1.lua",
      goo = "/usr/local/lua/lib/pack1_1.lua",
      foo1 = "/usr/local/lua/lib/pack1_2.lua",
      goo1 = "/usr/local/lua/lib/pack1_3.lua",
    }
</pre>
Then we create the package and define its metamethod:
<pre>
    pack1 = {}
    
    setmetatable(pack1, {__index = function (t, funcname)
      local file = location[funcname]
      if not file then
        error("package pack1 does not define " .. funcname)
      end
      assert(loadfile(file))()     -- load and run definition
      return t[funcname]           -- return the function
    end})
    
    return pack1
</pre>
After loading this package,
the first time the program executes <code>pack1.foo()</code> it
will invoke that <code>__index</code> metamethod,
which is quite simple.
It checks that the function has a corresponding file
and loads that file.
The only subtlety is that it must not only load the file,
but also return the function as the result
of the access.

<p>Because the entire system is written in Lua,
it is easy to change its behavior.
For instance, the functions may be defined in C,
with the metamethod using <code>loadlib</code> to load them.
Or we can set a metamethod in the global table to autoload
entire packages.
The possibilities are endless.

<p>
<hr/>
<table width="100%" class="nav">
<tr valign="top">
<td width="90%" align="left">
<small>
  Copyright &copy; 2003&ndash;2004 Roberto Ierusalimschy.  All rights reserved.
</small>
</td>
<td width="10%" align="right"><a href="16.html"><img border="0" src="right.png" alt="Next"></a></td>
</tr>
</table>


</body></html>

